//=============================================================================
// XBus 
//-----------------------------------------------------------------------------
// File        : info.c
// Description : 
// Author      : Ismail Sabry
// Date        : 1/30/2009
//=============================================================================
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#include <xbus_module.h>
#include <xbus_cell.h>
#include <xbus_interface.h>

int get_option(int argc, char **argv, char *xbus_name, int *xbus_module);
void xbus_check(t_XBUS_interface *interface);

static int alive=1;
static int all=1;

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void catch_signal(int sig)
{
  alive = 0;
  printf("\nSTOP (sig %d)\n\n", sig);
  fflush(stdout);
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int main (int argc, char **argv)
{
  char               xbus_name[XBUS_SIZE_NAME];
  int                xbus_id;
  t_XBUS_interface   interface;

#if 0
  snprintf(xbus_name, XBUS_SIZE_NAME-1, "test");
  xbus_id = 0;
#else
  if( get_option(argc, argv, xbus_name, &xbus_id) == -1)
    return -1;
#endif
  
  signal(SIGINT,  catch_signal);
  signal(SIGQUIT, catch_signal);
  signal(SIGTERM, catch_signal);

  if( XBUS_link(&interface, XBUS_CONSUMER, xbus_name, xbus_id) == -1)
    return -1;
  
  xbus_check(&interface);

  XBUS_unlink(&interface);
  
  return 0;

}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int get_option(int argc, char **argv, char *xbus_name, int *xbus_module)
{
  int    ret=-1;
  int    c;
  
  opterr = 0;
  
  if( (argc != 3) && (argc != 5) ) {
    printf("argc %d \n", argc);
    ret = -1;
  } else {
    while ((c = getopt (argc, argv, "n:m:?")) != -1) {
      switch (c) {
      case 'n': 
	// xbus name
	snprintf(xbus_name, XBUS_SIZE_NAME-1, "%s", optarg);
	ret = 0;
	break;
      case 'm': 
	// nb modules
	*xbus_module = atoi(optarg);
	all = 0;
	break;
     case '?':
      default :
	ret = -1;
	break;
      }
    }
  }
  
  if(ret != 0) {
    printf("\n");
    printf(" syntax: %s -n <name> -m <mid> \n", argv[0]);
    printf("    -n  xbus name\n");
    printf("    -m  module id\n");
    printf("    -?  this message \n");
    printf("\n");
  }

  return(ret);
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void xbus_check(t_XBUS_interface *interface)
{
  int               i, j;
  t_XBUS            *xbus;
  t_XBUS_module     *module;
  t_XBUS_cell       *cell, *next;

  xbus = interface->xbus;
  
  //---------------------------------------------------------------------------
  // check a partir de module=0 et cell=O
  if(all) {
    printf("[XXXXXXXXXX] XBUS Reference\n");
    if(xbus->head.magictag == XBUS_MAGICTAG_XBUS) {
      printf("[%p] XBUS \n", xbus);
      for(i=0; i<xbus->head.nb_module; i++) {
	module = XBUS_get_module_by_index(xbus, i);
	if(module->head.magictag == XBUS_MAGICTAG_MODULE) {
	  printf("[%p]  Module(%d) witer %d wcell %d \n", module, i, 
		 module->head.witer, module->head.wcell );
	  for(j=0; j<interface->xbus->head.nb_cell; j++) {	  
	    cell = XBUS_get_cell_by_index(xbus, module, j);
	    if(cell->head.magictag == XBUS_MAGICTAG_CELL) {
	      next = XBUS_get_next_cell(cell);
	      printf("[%p]   Cell(%d/%d) -> [%p](%d) \n", cell, i, j, next, (int)cell->body);
	    } else {
	      printf("[%p]   Bad Cell(%d/%d) \n", cell, i, j);
	      return;
	    }
	  }
	} else {
	  printf("[%p]  Bad Module(%d) wcell %d \n", module, i, module->head.wcell );
	  return;
	}
      }
    } else {
      printf("[%p] Bad XBUS \n", xbus);
      return;
    }
  }

  //---------------------------------------------------------------------------
  // check a partir de module=id et cell=wcell
  printf("[XXXXXXXXXX] XBUS Current\n");
  module = XBUS_get_module_by_index(xbus,  interface->id);

  if(module->head.magictag == XBUS_MAGICTAG_MODULE) {

    printf("[%p]  Module(%d) witer %d wcell %d \n", module, 
	   interface->id, module->head.witer, module->head.wcell );

    cell = XBUS_get_cell_by_index(xbus, module, module->head.wcell);
    if(cell->head.magictag == XBUS_MAGICTAG_CELL) {
      next = XBUS_get_next_cell(cell);
      printf("[%p]   Cell(%d/%d) -> [%p](%d)\n", cell, 
	     interface->id, module->head.wcell, next, (int)cell->body);
    } else {
      printf("[%p]   Bad Cell(%d/%d) \n", cell, interface->id, module->head.wcell);
      return;
    }
  } else {
    printf("[%p]  Bad Module(%d) wcell %d \n", module, interface->id, module->head.wcell );
    return;
  }

}

